package com.tl.boot.entity.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tl.boot.common.config.TokenConfig;
import com.tl.boot.common.constants.RedisConstant;
import com.tl.boot.common.enums.ResultEnum;
import com.tl.boot.common.utils.AesUtil;
import com.tl.boot.common.utils.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * com.tl.boot.common.utils -- TokenUtil
 * Description:
 * Created by joshua_liu <a href="mailto:joshualwork@163.com"></a>
 * On 2019/9/11 9:36
 */
@Component
public class TokenUtil {
    private static final Logger log = LoggerFactory.getLogger(TokenUtil.class);

    private static TokenConfig tokenConfig;

    private static RedisUtil redisUtil;

    @Autowired
    public void setTokenConfig(TokenConfig tokenConfig, RedisUtil redisUtil) {
        TokenUtil.tokenConfig = tokenConfig;
        TokenUtil.redisUtil = redisUtil;
    }

    public static Token decrypt(String encryptData) {
        if (StringUtils.isEmpty(encryptData)) {
            return null;
        }
        try {
            return JSONObject.parseObject(AesUtil.decrypt(encryptData, tokenConfig.getSalt()), Token.class);
        } catch (Exception e) {
            log.debug(String.format("token解析失败"));
            return null;
        }
    }

    public static ResultEnum validate(Token token) {
        if (token == null) {
            return ResultEnum.AUTH_NOTLOGIN;
        }
        if (token.getUserId() == null || token.getExpiredTime() == null) {
            return ResultEnum.REQUEST_ILLEGAL;
        }
        if (token.getExpiredTime() < System.currentTimeMillis()) {
            return ResultEnum.AUTH_NOTLOGIN;
        }
        return null;
    }

    public static String getEncryptToken(Long userId) {
        return redisUtil.get(String.format(RedisConstant.TOKEN_KEY, userId));
    }

    public static String generateEncryptToken(Long userId) {
        if (userId == null) {
            return null;
        }
        Token token = new Token();
        token.setUserId(userId);
        token.setExpiredTime(System.currentTimeMillis() + tokenConfig.getValidTime());
        String encryptData = AesUtil.encrypt(JSON.toJSONString(token), tokenConfig.getSalt());
        redisUtil.set(String.format(RedisConstant.TOKEN_KEY, userId), encryptData, token.getExpiredTime() / 1000);
        return encryptData;
    }


    public static void invalidateTokenInfo(Long userId) {
        if (userId != null) {
            redisUtil.set(String.format(RedisConstant.TOKEN_KEY, userId),
                    "", TimeUnit.MILLISECONDS.toSeconds(1));
        }
    }

    public static boolean allowTryAgain(Long userId) {
        String key = String.format(RedisConstant.LOGIN_LIMIT_KEY, userId);
        String timesStr = redisUtil.get(key);
        Integer times = StringUtils.isEmpty(timesStr) ? null : Integer.parseInt(timesStr);
        if (times == null) {
            redisUtil.set(key, "1", TimeUnit.DAYS.toSeconds(1));
        } else if (times != null && times > 5) {
            return false;
        } else if (times != null && times <= 5) {
            redisUtil.incr(key, 1);
        }
        return true;
    }

    public static void clearLoginLimit(Long userId) {
        if (userId != null) {
            redisUtil.set(String.format(RedisConstant.LOGIN_LIMIT_KEY, userId), "", TimeUnit.MILLISECONDS.toSeconds(1));
        }
    }


}
